package com.hb.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.BeanNameViewResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

/**
 * 在大多数场景下，ContentNegotiatingViewResolver 会假设客户端需要 HTML，如 ContentNegotiationManager 配置所示。但是，如果客户端指定了它想要 JSON（通过在请求路径上使用
 * “.json” 扩展名或 Accept 头部信息）的话，那么 ContentNegotiatingViewResolver 将会查找能够处理 JSON 视图的视图解析器。如果逻辑视图的名称为 “spittles”，那么我们所配置的
 * BeanNameViewResolver 将会解析 spittles() 方法中所声明的 View。这是因为 bean 名称匹配逻辑视图的名称。如果没有匹配的 View 的话，ContentNegotiatingViewResolver
 * 将会采用默认的行为，将其输出为 HTML。
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ViewResolver cnViewResolver(ContentNegotiationManager cnm) {
        ContentNegotiatingViewResolver cnvr = new ContentNegotiatingViewResolver();
        // 这样设置之后 ContentNegotiatingViewResolver 将会使用 ContentNegotiationManager 所定义的行为。
        cnvr.setContentNegotiationManager(cnm);
        return cnvr;
    }

    /**
     * 如果使用 Java 配置的话，获得 ContentNegotiationManager 的最简便方法就是扩展 WebMvcConfigurerAdapter 并重载 configureContentNegotiation() 方法。
     * configureContentNegotiation() 方法给定了一个 ContentNegotiationConfigurer 对象。ContentNegotiationConfigurer 中的一些方法对应于
     * ContentNegotiationManager 的 Setter 方法，这样我们就能在 ContentNegotiationManager 创建时，设置任意内容协商相关的属性。
     * @param configurer
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        // 设置了默认的内容类型
//        configurer.defaultContentType(MediaType.APPLICATION_JSON);
        // 默认会使用 HTML 视图
        configurer.defaultContentType(MediaType.TEXT_HTML);
    }

    /**
     * 以 bean 的形式查找视图
     * @return
     */
    @Bean
    public ViewResolver beanNameViewResolver() {
        return new BeanNameViewResolver();
    }

    /**
     * 将 "spittles" 定义为 JSON 视图，也就是对特定的视图名称将会渲染为 JSON 输出。
     * @return
     */
    @Bean
    public View spittles() {
        return new MappingJackson2JsonView();
    }
}
